package com.minglead.springboot.common.config;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.core.io.DefaultResourceLoader;
import com.minglead.springboot.common.utils.PropertiesLoader;
import com.minglead.springboot.common.utils.StringUtils;

/**
 * 全局配置类
 * 有时候需要被前端fns.tld 静态调用，无法使用@Value等注解进行注入
 * 必须要读取配置文件(根据spring boot 读取application-xxx.properties)相关文件
 */
public class Global {
	/**
	 * 当前对象实例
	 */
	private static Global global = new Global();
	/**
	 * 保存全局属性值
	 */
	private static Map<String, String> map = new HashMap<String,String>();
	
	/**
	 * 属性文件加载对象
	 */
	private static PropertiesLoader loader = new PropertiesLoader("minglead.properties");
	
	/**
	 * spring boot 属性文件加载对象(由于spring boot支持在配置文件指定配置文件，这里不做加载)
	 */
	
	private static PropertiesLoader loaderSpringBoot = null;

	/**
	 * 显示/隐藏
	 */
	public static final String SHOW = "1";
	public static final String HIDE = "0";

	/**
	 * 是/否
	 */
	public static final String YES = "1";
	public static final String NO = "0";
	
	/**
	 * 对/错
	 */
	public static final String TRUE = "true";
	public static final String FALSE = "false";    
	
	
	/**
	 * 获取当前对象实例
	 */
	public static Global getInstance() {
		return global;
	}
	
	/**
	 * 获取配置
	 * @see ${fns:getConfig('adminPath')}
	 */
	public static String getConfig(String key) {
		String value = map.get(key);
		if (value == null){
			value = loader.getProperty(key);
			map.put(key, value != null ? value : StringUtils.EMPTY);
		}
		return value;
	}
	
	public static String getConfigSpringBoot(String key) {
		initLoaderSpringBoot();
		String value = map.get(key);
		if (value == null){
			value = loaderSpringBoot.getProperty(key);
			map.put(key, value != null ? value : StringUtils.EMPTY);
		}
		return value;
	}	
	
	/**
	 * 初始化spring boot 配置文件加载对象
	 * @return 
	 */
	public static void initLoaderSpringBoot() {
		if(loaderSpringBoot==null){
			//默认配置文件
			PropertiesLoader loaderSpringBootTemp = new PropertiesLoader("application.properties");
			//确认是否有二次外联，如果有，覆盖
			String active = loaderSpringBootTemp.getProperty("spring.profiles.active");
			
			if(!StringUtils.isEmpty(active)){
				//二次外联
				loaderSpringBoot = new PropertiesLoader("application-"+active+".properties");
			}else{
				loaderSpringBoot = loaderSpringBootTemp;
			}
		}
	}	
	
	
	
	
	/**
	 * 获取项目名(例如：/springboot)
	 * spring boot 配置
	 */
	public static String getContextPath() {
		return getConfigSpringBoot("server.servlet.path");
	}
	
	/**
	 * 获取管理端根路径
	 */
	public static String getAdminPath() {
		return getConfig("adminPath");
	}
	
	/**
	 * 获取前端根路径
	 */
	public static String getFrontPath() {
		return getConfig("frontPath");
	}
	
	/**
	 * 获取URL后缀
	 */
	public static String getUrlSuffix() {
		return getConfig("urlSuffix");
	}
	
	/**
	 * 是否是演示模式，演示模式下不能修改用户、角色、密码、菜单、授权
	 */
	public static Boolean isDemoMode() {
		String dm = getConfig("demoMode");
		return "true".equals(dm) || "1".equals(dm);
	}
	
	/**
	 * 在修改系统用户和角色时是否同步到Activiti
	 */
	public static Boolean isSynActivitiIndetity() {
		String dm = getConfig("activiti.isSynActivitiIndetity");
		return "true".equals(dm) || "1".equals(dm);
	}
    
	/**
	 * 页面获取常量
	 * @see ${fns:getConst('YES')}
	 */
	public static Object getConst(String field) {
		try {
			return Global.class.getField(field).get(null);
		} catch (Exception e) {
			// 异常代表无配置，这里什么也不做
		}
		return null;
	}

	/**
	 * 获取上传文件的根目录
	 * @return
	 */
	public static String getUserfilesBaseDir() {
		String dir = getConfig("userfiles.basedir");
		//有待完善
		return null;
	}
	
    /**
     * 获取工程路径
     * @return
     */
    public static String getProjectPath(){
    	// 如果配置了工程路径，则直接返回，否则自动获取。
		String projectPath = Global.getConfig("projectPath");
		if (StringUtils.isNotBlank(projectPath)){
			return projectPath;
		}
		try {
			File file = new DefaultResourceLoader().getResource("").getFile();
			if (file != null){
				while(true){
					File f = new File(file.getPath() + File.separator + "src" + File.separator + "main");
					if (f == null || f.exists()){
						break;
					}
					if (file.getParentFile() != null){
						file = file.getParentFile();
					}else{
						break;
					}
				}
				projectPath = file.toString();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return projectPath;
    }
	
}
